/*
   Copyright (c) 2005 Lucas Mello Schnorr <schnorr@gmail.com>
   
   This file is part of DIMVisual.
   
   DIMVisual is free software; you can redistribute it and/or modify it under
   the terms of the GNU Lesser General Public License as published by the
   Free Software Foundation; either version 2 of the License, or (at your
   option) any later version.
   
   DIMVisual is distributed in the hope that it will be useful, but WITHOUT ANY
   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
   for more details.
   
   You should have received a copy of the GNU Lesser General Public License
   along with DIMVisual; if not, write to the Free Software Foundation, Inc.,
   59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
*/
#include "MPIRASTROConverter.h"
#include "OneToAll.h"

static OneToAll *scatter;
static OneToAll *scatterv;


@implementation MPIRASTROConverter (Scatter)
- (id) convertEventScatter: (GEvent *) event
{
	NSMutableArray *ret = nil;
	NSString *container;
	
	GFields *f = [event fields];

	NSString *machine, *thread, *node, *identifier, *time;
	NSString *int32AtIndex0, *int32AtIndex1, *int32AtIndex2;
	NSString *stringAtIndex0;


        machine = [[f fieldWithSimpleStringKey:@"machine"] description];
        thread = [[f fieldWithSimpleStringKey: @"thread"] description];
        node = [[f fieldWithSimpleStringKey: @"node"] description];
        identifier = [[event identifier] description];
        time = [[event timestamp] description];
        int32AtIndex0 = [[f fieldWithSimpleStringKey: @"uint32-0"] description];
        int32AtIndex1 = [[f fieldWithSimpleStringKey: @"uint32-1"] description];
        int32AtIndex2 = [[f fieldWithSimpleStringKey: @"uint32-2"] description];
        stringAtIndex0 = [[f fieldWithSimpleStringKey: @"string-0"] description];
	
	if (scatter == nil){
		scatter = [[OneToAll alloc] init];
	}
	if (scatterv == nil){
		scatterv = [[OneToAll alloc] init];
	}
	
	ret = [[NSMutableArray alloc] init];

	container = [provider identifierForEntity: 
		[NSArray arrayWithObjects: @"Machine", @"Thread", nil]
				ids:
		[NSArray arrayWithObjects: machine, thread, nil]];

	if (container == nil){
		[ret release];
		return nil;
	}
	
	int etype = atoi ([identifier cString]);


	/* MPI_SCATTER_IN */
	if (etype == MPI_SCATTER_IN){
		NSString *count = int32AtIndex0;
		NSString *size = int32AtIndex1;
		NSString *root = int32AtIndex2;
		NSString *members = stringAtIndex0;
		
		//int sendcnt = atoi([int32AtIndex0 cString]);

		[scatter memberEntering: container
			andEventNode: node
			andEventTime: time
			andRootNode: root
			andCommSize: size
			andMembersId: members];

		PajeSetState *set;
		set = [self addPajeSetState: @"MPI_SCATTER" time: time container: container];
		[set retain];
		[set addFieldNamed: @"COUNT" withType: @"string"];
		[set setValue: count forFieldNamed: @"COUNT"];
		[ret addObject: set];
		[set release];

	/* MPI_SCATTER_OUT */
	}else if (etype == MPI_SCATTER_OUT){
		NSString *recvcnt = int32AtIndex0;
		NSString *root = int32AtIndex1;
		NSString *members = stringAtIndex0;

		[ret addObjectsFromArray: [scatter memberExiting: container andEventTime: time andOperationName: @"scatter" andRootNode: root andMembersId: members andProvider: provider]];

		[ret addObject: [self addPajeSetState: @"running" time: time container: container]];
		
		PajeNewEvent *ev;
		ev = [[PajeNewEvent alloc] initWithTime: time];
		[ev setContainer: container];
		[ev setEntityType: [provider aliasToName: @"Events"]];
		[ev setValue: [NSString stringWithFormat: @"MPI_Scatter (%@ bytes)", recvcnt]];
		[ret addObject:ev];
		[ev release];

	
	/* MPI_SCATTERV_IN */
	}else if (etype == MPI_SCATTERV_IN){
		NSString *size = int32AtIndex0;
		NSString *root = int32AtIndex1;
		NSString *members = stringAtIndex0;

		[scatterv memberEntering: container
			andEventNode: node
			andEventTime: time
			andRootNode: root
			andCommSize: size
			andMembersId: members];
		[ret addObject: [self addPajeSetState: @"MPI_SCATTERV" time: time container: container]];

	/* MPI_SCATTERV_OUT */
	}else if (etype == MPI_SCATTERV_OUT){
		NSString *recvcnt = int32AtIndex0;
		NSString *root = int32AtIndex1;
		NSString *members = stringAtIndex0;
		

		[ret addObjectsFromArray: [scatterv memberExiting: container andEventTime: time andOperationName: @"scatterv" andRootNode: root andMembersId: members andProvider: provider]];

		[ret addObject: [self addPajeSetState: @"running" time: time container: container]];

		PajeNewEvent *ev;
		ev = [[PajeNewEvent alloc] initWithTime: time];
		[ev setContainer: container];
		[ev setEntityType: [provider aliasToName: @"Events"]];
		[ev setValue: [NSString stringWithFormat: @"MPI_Scatterv (%@ bytes)", recvcnt]];
		[ret addObject:ev];
		[ev release];
	}

	[ret autorelease];
	return ret;
}
@end
